// 可变参数模板和普通模板的语义时一样的，指示写法上稍微有区别，声明可变参数模板时需要在 typename 或 class 后面带上省略号

#include <initializer_list>
#include <iostream>
#include <tuple>

using namespace std;


//可变参数模板函数
//1. 使用递归函数方式展开参数包
//2. 使用逗号表达式和初始化列表方式展开参数包  
    //逗号表达式:
    //var = (count=19, incr=10, count+1); 首先把 count 赋值为 19，把 incr 赋值为 10，然后把 count 加 1，最后，把最右边表达式 count+1 的计算结果 20 赋给 var。上面表达式中的括号是必需的，因为逗号运算符的优先级低于赋值操作符。
    //逐步计算，得到最后一个值
template<class T>
void printarg(T t)
{
    cout << t << endl;
}

template<typename... Args>
void expand(Args... args)
{
    std::initializer_list<int>{(printarg(args), 0)...}; //逗号表达式 
}



//可变参数模板类
template<typename... Args> struct Sum;
template<typename First, typename... Rest>
struct Sum<First, Rest...>
{
    enum { value = Sum<First>::value + Sum<Rest...>::value };
};

template<typename Last> 
struct Sum<Last>
{
    enum {value = sizeof(Last)};
};

int main(void)
{
    expand(1, 2, 3, 4);

    std::tuple<int> tp1 = std::make_tuple(1);
    std::tuple<int, double> tp2 = std::make_tuple(1, 2.5);
    std::tuple<int, double ,string> tp3 = std::make_tuple(1, 2.5, "");
    return 0;
}
